﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ParsecParser;
using ParsecParser.Data;
using ParsecParser.Helpers;
using ParsecParser.Communication;
using ParsecParser.Display;
using ParsecClient.Classes;

namespace ParsecClient
{
    /// <summary>
    /// Interaction logic for DpsMeter.xaml
    /// </summary>
    public partial class DpsMeter : Window
    {
        public enum DamageViewMode
        {
            None=0,
            LastFive = 1,
            AbilityRank = 2
        }
        public DamageViewMode CurrentMode { get; set; }
        public DpsMeter()
        {
            InitializeComponent();
            CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, new ExecutedRoutedEventHandler(delegate(object sender, ExecutedRoutedEventArgs args) { this.Close(); })));
            CurrentMode = DamageViewMode.LastFive;
        }

        public void BindData(CombatDetails cd)
        {
            if (cd != null && cd.HasEvents())
            {
                txtDps.ToolTip = cd.DamageOut.ToString("N0");
                txtDps.Text = (cd.DamageOut / cd.CombatTimeSpan.TotalSeconds).ToString("N0");
                List<CombatLogEvent> damageOutEvents = cd.GetEvents(new CombatLogFilterParameters() { ShowOutgoingDamage = true });
                icAttacks.ItemsSource = damageOutEvents.Skip(damageOutEvents.Count - 5).Reverse().Select(x => new
                {
                    Name = x.Ability.DisplayName,
                    Value = (x.IsCrit ? "*" : "") + x.Value.ToString("N0"),
                    IsCrit = x.IsCrit,
                    DamageColor = x.DamageType.GetDamageForegroundColor()
                }).ToList();                    

                double sumTotal = cd.DamageOut;

                icAttackDmg.ItemsSource = damageOutEvents.GroupBy(x => x.Ability.DisplayName)
                        .Select(x => new
                        {
                            Name = x.Key,
                            Value = (sumTotal > 0 ? ((double)x.Sum(y => y.Value) / sumTotal) * 100 : 0).ToString("N0"),
                            PctDamage = sumTotal > 0 ? ((double)x.Sum(y => y.Value) / sumTotal) * 100 : 0
                        }).OrderByDescending(x => x.PctDamage).ToList();
                SetViewMode();
            }
            else
            {
                txtDps.ToolTip = string.Empty;
                txtDps.Text = string.Empty;
                icAttacks.ItemsSource = null;
                icAttackDmg.ItemsSource = null;
                SetViewMode();
            }
        }
        public void SetViewMode()
        {
            if (CurrentMode == DamageViewMode.LastFive)
            {
                icAttackDmg.Visibility = System.Windows.Visibility.Collapsed;
                icAttacks.Visibility = System.Windows.Visibility.Visible;
            }
            else if (CurrentMode == DamageViewMode.AbilityRank)
            {
                icAttackDmg.Visibility = System.Windows.Visibility.Visible;
                icAttacks.Visibility = System.Windows.Visibility.Collapsed;
            }
            else
            {
                icAttackDmg.Visibility = System.Windows.Visibility.Collapsed;
                icAttacks.Visibility = System.Windows.Visibility.Collapsed;
            }

        }
        private void ModeHandler(object sender, RoutedEventArgs e)
        {
            try
            {
                if (sender == btnLast5)
                {
                    CurrentMode = DamageViewMode.LastFive;
                }
                else if (sender == btnRank)
                {
                    CurrentMode = DamageViewMode.AbilityRank;
                }
                else
                {
                    CurrentMode = DamageViewMode.None;
                }
                SetViewMode();
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", string.Format("Error on {0} Pop Out btnIncreaseOpacity_Click", this.Title), ex, null, true);
            }
        }
        public double GetBackgroundOpacity()
        {
            return BorderBackground.Opacity;
        }
        public void SetBackgroundOpacity(double opacity)
        {
            BorderBackground.Opacity = opacity;
            BorderSolid.Opacity = opacity;
            BorderBlur.Opacity = opacity;
        }

        public void DragWindow(object sender, MouseButtonEventArgs args)
        {
            try
            {
                this.WindowState = WindowState.Normal;
                DragMove();
                args.Handled = true;
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", string.Format("Error on {0} Pop Out DragWindow", this.Title), ex, null, true);
            }
        }
        private void btnIncreaseOpacity_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (BorderBackground.Opacity < 1)
                {
                    BorderBackground.Opacity += .1;
                    BorderSolid.Opacity += .1;
                    BorderBlur.Opacity += .1;
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", string.Format("Error on {0} Pop Out btnIncreaseOpacity_Click", this.Title), ex, null, true);
            }
        }

        private void btnDecreaseOpacity_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (BorderBackground.Opacity > 0)
                {
                    BorderBackground.Opacity -= .1;
                    BorderSolid.Opacity -= .1;
                    BorderBlur.Opacity -= .1;
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", string.Format("Error on {0} Pop Out btnDecreaseOpacity_Click", this.Title), ex, null, true);
            }
        }

        private void btnIncreaseSize_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (this.Width < 1000)
                {
                    this.Width += 10;
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", string.Format("Error on {0} Pop Out btnIncreaseSize_Click", this.Title), ex, null, true);
            }
        }

        private void btnDecreaseSize_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (this.Width > 100)
                {
                    this.Width -= 10;
                }
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", string.Format("Error on {0} Pop Out btnIncreaseSize_Click", this.Title), ex, null, true);
            }
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (Application.Current.MainWindow != null)
                {
                    ((ParsecWindow)Application.Current.MainWindow).btnDpsMeter.IsChecked = false;
                }
                this.Hide();
            }
            catch (Exception ex)
            {
                ((App)Application.Current).HandleError("Error", string.Format("Error on {0} Pop Out btnClose_Click", this.Title), ex, null, true);
            }
        }
    }
}
